﻿using Castle.DynamicProxy;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Common.AutofaExt.AOP
{
    //1.Nuget引入：Autofac.Extras.DynamicProxy
    //2.扩展一个IInterceptor 实现方法
    //3.注册对象和具体之间的关系的时候，需要执行要支持AOP扩展EnableClassInterceptors
    //4.把要扩展aop的方法定义为  virtual 方法
    //5.把扩展的IInterceptor 也要注册到容器中去

    //一、通过EnableClassInterceptors来支持的时候
    //1.需要把Intercept标记到具体的实现类上---扩展IInterceptor也要引用进来
    //2.特点:必须钥匙虚方法才会进入到扩展Iinterceptor来---才能支持aop扩展

    //二、通过EnableInterfaceInterceptors来支持的时候
    //1.需要把Intercept标记到抽象--接口--扩展IInterceptor也要引用到抽象这
    //2.特点:只要是实现了这接口,无论是否是虚方法,都可以进入到IInterceptor中来,也就是都可以支持AOP扩展

    public class CustomerInterceptor : IInterceptor
    {
        //可以获取到用户的信息,和一些httpcontext的信息
        private readonly IHttpContextAccessor _accessor;

        public CustomerInterceptor(IHttpContextAccessor accessor)
        {
            _accessor = accessor;
        }


        /// <summary>
        /// 切入者逻辑
        /// 使用了Intercept方法把要调用的Call方法给包裹起来了
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            dynamic a = invocation.InvocationTarget;

            string menuName=a.menuName;

            //var info =a.GetProperties();
            //foreach (var item in info)
            //{
            //    if (item.Name == "menuName")
            //    {
            //        object b = item.GetValue(this, null);
            //    }

            //}

            HttpContext httpContext = _accessor.HttpContext;
            //用户信息
            //httpContext.User.Claims
            //用户路径
            //string path= httpContext.Request.Path.Value;
            
            {
                Console.WriteLine("Before:" + JsonConvert.SerializeObject(invocation.Arguments));
            }
            invocation.Proceed();//这句话执行真实的方法
            {
                //将结果返回回来插入mongodb
                dynamic ddd=invocation.ReturnValue;

                if (ddd!=null)
                {
                    Console.WriteLine(ddd.before);
                    Console.WriteLine(ddd.after);
                    Console.WriteLine(ddd.msg);
                }
                
             
                Console.WriteLine("After:" + JsonConvert.SerializeObject(invocation.ReturnValue));
            }

        }
    }
}
